# -*- coding: UTF-8 -*-
__author__ = 'kennyh'
from twisted.internet.protocol import DatagramProtocol
from twisted.internet.protocol import Factory
from twisted.internet import threads
from MysqlSet import *
from logger import logger
from constant import *

from unpack import *
from lorawan_mqtt import *
from nbiot_client import *

import binascii
import random
import traceback
import string
import copy
import struct
import json
import time
from datetime import datetime as dt_date_time
import global_buffer
from envmonitor_unpack import *
from pack import PackSendData

from multiprocessing import Process,Queue
#from restful_server import start_nbiot_monitor

REGISTER_REQ = 0x11
REGISTER_RESP = 0x12
HEARTBEAT_REQ = 0x13
SENDDATA_REQ = 0x14
SENDDATA_RESP = 0x15
CMD_REQ = 0x16
CMD_RESP = 0x17
DATA_REPORT_REQ = 0x18
DATA_SYNC_RESP = 0x19
SYSTEM_RW_CMD_REQ = 0x1A
SYSTEM_RW_CMD_RESP = 0x1B
APP_UPGRADE_REQ = 0x1C
APP_UPGRADE_RESP = 0x1D

ULP_REGISTER_REQ = 0x21
ULP_REGISTER_RESP = 0x22
ULP_DATA_REPORT_REQ = 0x23
ULP_DATA_REPORT_RESP = 0x24

SERVER_ADDR_TYPE = 0X00
GPRS_DATA_TYPE = 0X01
PATROL_SETTING_TYPE = 0X02
SYSTEM_VERSION_TYPE = 0x03



def covertLorawanAddress(strAddress):
    hexaddress = []

    datalen = len(strAddress)
    for n in range(datalen):
        if n % 2 == 0:
            hexaddress.append(strAddress[n:n + 2])

    return ':'.join(hexaddress)

def covertLorawanMsg(srcData):
    msgdata = []

    datalen = len(srcData)
    for n in range(datalen):
        if n % 2 == 0:
            msgdata.append(srcData[n:n + 2])

    return ' '.join(msgdata)


class UDPDataConvert(object):
    def __init__(self):
        pass

    def BYTEToInt(self, src):
        return int(binascii.b2a_hex(src), 16)

    def Reverse(self,Src):
        Desc =''
        for item in Src:
            Desc = item + Desc
        return Desc

    def print_string2hex(self, stringData):
        try:
            send_data = ""
            for k, count in enumerate(stringData):
                hexstr = binascii.b2a_hex(count)
                send_data = "%s%s"%(send_data,hexstr)
            logger.info("Data %s" % (send_data))
        except Exception, e:
            logger.error("print_string2hex error: %s"% str(e))

    def decodeData(self, Src):
        try:
            msgdata = {}
            self.print_string2hex(Src)
            functionCode = self.BYTEToInt(Src[0])
            logger.info("functionCode 0x%x" % functionCode)
            if functionCode == REGISTER_REQ \
            or functionCode == ULP_REGISTER_REQ \
            or functionCode == ULP_DATA_REPORT_REQ \
            or functionCode == HEARTBEAT_REQ \
            or functionCode == CMD_RESP \
            or functionCode == SENDDATA_RESP \
            or functionCode == SENDDATA_REQ \
            or functionCode == DATA_REPORT_REQ \
            or functionCode == SYSTEM_RW_CMD_RESP \
            or functionCode == APP_UPGRADE_RESP:
                PayloadLen = self.BYTEToInt(Src[3])
                PayloadLen |= (self.BYTEToInt(Src[2]) << 8)
                datalen = PayloadLen+4
                Payload = Src[4:datalen]

                checksum = 0
                if len(Src) < datalen+1:
                    logger.error("decodeData error,receive lenght %d, and data lenght %d)"%(len(Src), datalen))

                for data in Src[0:datalen]:
                    item, = struct.unpack('B', data)
                    checksum += item
                    checksum &= 0xFF
                logger.info("checksum 0x%x" % checksum)
                rCheckSum = self.BYTEToInt(Src[datalen])
                if checksum == rCheckSum:
                    msgdata = {
                        'functionCode': functionCode,
                        'SeqSequence': self.BYTEToInt(Src[1]),
                        'PayloadLen': PayloadLen,
                        'payload': Payload,
                        'checksum': checksum}
                    return True, msgdata

            logger.info("msgdata %s" % str(msgdata))

            return False, msgdata
        except Exception,exception:
            logger.error(traceback.format_exc())
            return False, {}

    def encodeData(self, msgdata):
        try:
            Dest = ''
            Dest += self.Reverse(struct.pack('B', msgdata['functionCode']))
            Dest += self.Reverse(struct.pack('B', msgdata['SeqSequence']))
            payloadlen = msgdata['PayloadLen']

            lendata0 = ((payloadlen >> 8) & 0xff)
            lendata1 = (payloadlen & 0xff)
            logger.info("payloadlen %d, lendata0 %d , lendata0 %d" % (payloadlen, lendata0, lendata1))
            Dest += self.Reverse(struct.pack('B', lendata0))
            Dest += self.Reverse(struct.pack('B', lendata1))
            payload = msgdata['payload']
            #logger.info(type(payload))
            if type(payload) == str:
                Dest += payload
            else:
                for data in payload:
                    Dest += self.Reverse(struct.pack('B', data))
            check_code = 0
            for data in Dest:
                check_code += struct.unpack('B', data)[0]
            check_code = struct.pack('I', check_code)[0]
            Dest += check_code
            self.print_string2hex(Dest)
            return Dest
        except Exception,exception:
            logger.error(traceback.format_exc())
            return []


class UDPServerProtocol(object):
    def __init__(self, factory, projectid, netid, lampid, network_Type, gateway_Type, clientName, patrolinterval, devicetype = 0):
        self.factory = factory
        self.clientName = clientName
        self.addr = []
        self.projectid = projectid
        self.networkid = netid
        self.lampid = lampid
        self.deviceid = ''
        self.lasttime = dt_date_time.now()
        self.networkCSQ = 0
        self.clientStatus = 0
        self.networkType = network_Type
        self.gatewayType = gateway_Type
        self.devicetype = devicetype
        self.cmdsmgseq = 0
        self.send_cmd_dict = {}
        self.patrolinterval = patrolinterval

    def getNetworkAddr(self):
        return self.addr

    def setNetworkAddr(self, patrolinterval):
        self.patrolinterval = patrolinterval

    def updateNetworkAddr(self, netAddr):
        if self.networkType == NBIOT_TYPE:
            self.lasttime = dt_date_time.now()
            self.deviceid = netAddr
            self.factory.mysqlDb.reset_network_status(
                [{'network_id': self.networkid, 'status': 1, 'ip': '', 'port': ''}])
        elif self.networkType == UDP_TYPE:
            self.addr = netAddr
            ip, port = self.addr
            self.factory.mysqlDb.reset_network_status(
                [{'network_id': self.networkid, 'status': 1, 'ip': ip, 'port': port}])
        elif self.networkType == LORA_WAN_TYPE:
            self.clientName = netAddr
            self.factory.mysqlDb.reset_network_status(
                [{'network_id': self.networkid, 'status': 1, 'ip': '', 'port': ''}])
        logger.info("client name %s, updata addr %s" % (self.clientName, str(self.addr)))

    def updateConnectTime(self, netCSQ, clientStatu):
        self.lasttime = dt_date_time.now()

        self.networkCSQ = netCSQ
        self.clientStatus = clientStatu
        logger.info("client name %s, CSQ %d, status %d" % (self.clientName, netCSQ, clientStatu))

    def cleanUp(self):
        try:
            if self.networkid > 0:
                self.factory.mysqlDb.reset_network_status(
                    [{'network_id': self.networkid, 'status': 0, 'ip': '', 'port': ''}])

            if self.networkType == NBIOT_TYPE:
                if self.networkid in self.factory.nbiot_netlists:
                    logger.info("%s client lost %s" % (self.clientName, str(self.addr)))
                    del self.factory.nbiot_netlists[self.networkid]
            elif self.networkType == UDP_TYPE:
                if self.networkid in self.factory.connections:
                    logger.info("%s client lost %s" % (self.clientName, str(self.addr)))
                    del self.factory.connections[self.networkid]
            elif self.networkType == LORA_WAN_TYPE:
                int_address = self.clientName
                if int_address in self.factory.lorawan_netlists:
                    logger.info("%s client lost %s" % (self.clientName, str(self.addr)))
                    del self.factory.lorawan_netlists[int_address]
        except Exception,exception:
            logger.error(traceback.format_exc())
            return []

class UDPServerFactoryProtocol(DatagramProtocol):
    def __init__(self, storageTag):

        self.is_UDPdecode_thread_locked = False
        self.UDPheart_beat_record_time = dt_date_time.now()  #5s
        self.decode_thread_record_time = dt_date_time.now()  #per 1s

        self.storageTag = storageTag
        self.msg_buffer = storageTag.msg_buffer
        self.mysqlDb = storageTag.mysqlDb
        self.dataConvert = UDPDataConvert()
        self.connections = {}
        self.nbiot_netlists = {}
        self.lorawan_netlists = {}

        self.data_decode = storageTag.data_decode

        self.envmonitor_decode = ENVMonitorUnPack()

        self.timetick = 0
        self.lorawan_send_cmd_dict = {}
        self.nbiot_send_cmd_dict = {}

        self.MainThread = threads.deferToThread(self.UDPServer_main_thread)

        self.MainThread.addCallback(self.send_data_success)
        self.ReceiveCMDThread = threads.deferToThread(self.ReceiveCMD_thread)
        self.ReceiveCMDThread.addCallback(self.send_data_success)

        if LORA_WAN_ENABLE == 1:
            self.dp_lorawan = LORAWAN_MQTTClass(self)

        if NBIOT_ENABLE == 1:
            self.nbiot_client = NBiotClient(NBIOT_SERVER_ADDRESS, NBIOT_SERVER_PORT, NBIOT_SERVER_APPID,
                                            NBIOT_SERVER_KEY)
            self.nbiot_client.authentication()
            self.nbiot_client.nbiot_server_subscribe()
        logger.info("UDPServer init!!!!")

    def getAddrByNetworkid(self, netid):

        if netid in self.connections:
            client_item = self.connections[netid]
            return client_item.addr
        return False

    def getClientBydevid(self, deviceid):
        connectdist_key = self.nbiot_netlists.keys()
        for networkid in connectdist_key:
            client_item = self.nbiot_netlists[networkid]
            if client_item.deviceid == deviceid:
                client_item.lasttime = dt_date_time.now()
                return client_item
        return False

    def getClientByAddr(self, addr):
        connectdist_key = self.connections.keys()
        for netid in connectdist_key:
            client_item = self.connections[netid]
            if client_item.addr == addr:
                return client_item
        return False

    def datagramReceived(self, msg, addr):
        logger.info("receive data to %s" % str(addr))
        self.msg_buffer.append({'protype': 'udp', 'addr': addr, 'msgdata': msg})

    def datawrite(self, buf, addr):
        logger.info("send data to %s" % str(addr))
        self.transport.write(buf, addr)

    def registerResponse(self, addr, networkid, protocoltype = 1, flag = True, functioncode = REGISTER_RESP):
        try:
            msgdata = {}
            netdata = []
            logger.info("registerResponse flag %s" % str(flag))
            if flag == True:

                netdata.append((networkid >> 24) & 0xff)
                netdata.append((networkid >> 16) & 0xff)
                netdata.append((networkid >> 8) & 0xff)
                netdata.append(networkid & 0xff)

                if protocoltype == 2:
                    #result, netid = self.mysqlDb.get_netid_from_nework(networkid)

                    #netidsting = netid.encode("utf-8")
                    #netidBytes = bytearray.fromhex(netidsting)
                    #logger.info(type(netidBytes))
                    #logger.info("netidsting %s" % str(netidBytes[0]))
                    #logger.info("netidsting %s" % str(netidBytes[1]))
                    netdata.append(0x00)
                    netdata.append(0x01)

                    result, address_list = self.mysqlDb.get_lampinfo_groupby_network(networkid)
                    addr_count = len(address_list)
                    netdata.append(addr_count & 0xff)

                    for address in address_list:
                        addrnum = int(address.get("address"), 16)
                        logger.info(hex(addrnum))
                        netdata.append((addrnum >> 24) & 0xff)
                        netdata.append((addrnum >> 16) & 0xff)
                        netdata.append((addrnum >> 8) & 0xff)
                        netdata.append(addrnum & 0xff)
                msgdata ={
                    'functionCode': functioncode,
                    'SeqSequence': 0,
                    'PayloadLen': len(netdata),
                    'payload': netdata,
                    'checksum': 0}
            else:
                msgdata = {
                    'functionCode': functioncode,
                    'SeqSequence': 0,
                    'PayloadLen': -1,
                    'payload': [0xF0],
                    'checksum': 0}


            sendbuf = self.dataConvert.encodeData(msgdata)
            if protocoltype == NBIOT_TYPE:
                self.nbiot_client.nbiot_sendCommand(addr, sendbuf)
            else:
                self.datawrite(sendbuf, addr)

            return True
        except Exception,exception:
            logger.error(traceback.format_exc())
            return False

    def systemdata_rw_cmd_request(self, client, functionCode, typeCode, systemdata, cmd_client, sendtimes=0):
        try:
            msgdata = {}
            addr = client.addr
            sequence = client.cmdsmgseq
            client.cmdsmgseq = (1 + sequence) & 0xff

            senddata = self.dataConvert.Reverse(struct.pack('B', functionCode))
            senddata += self.dataConvert.Reverse(struct.pack('B', typeCode))
            if functionCode == 0x00:
                if type(systemdata) == int:
                    senddata += self.dataConvert.Reverse(struct.pack('B', systemdata))
                else:
                    senddata += systemdata.encode("utf-8")
            payloadlen = len(senddata)
            msgdata = {
                'functionCode': SYSTEM_RW_CMD_REQ,
                'SeqSequence': sequence,
                'PayloadLen': payloadlen,
                'payload': senddata,
                'checksum': 0}

            sendbuf = self.dataConvert.encodeData(msgdata)

            if sendtimes == 0:
                client.send_cmd_dict[sequence] = {
                    'lasttime': dt_date_time.now(),
                    'times': sendtimes,
                    'sendbuf': sendbuf,
                    "cmd_client": cmd_client}
            else:
                if sequence in client.send_cmd_dict:
                    client.send_cmd_dict[sequence]['times'] = sendtimes
            if client.networkType == NBIOT_TYPE:
                self.nbiot_client.nbiot_sendCommand(client.deviceid, sendbuf)
            else:
                self.datawrite(sendbuf, addr)

            return True
        except Exception, exception:
            logger.error(traceback.format_exc())
            return False

    def lorawan_rw_cmd_request(self, address, systemdata, cmd_client, sendtimes=0):
        try:
            lora_address = covertLorawanAddress(address)
            lora_msg = covertLorawanMsg(binascii.b2a_hex(systemdata))
            if sendtimes == 0:
                self.lorawan_send_cmd_dict[address] = {
                    'lasttime': dt_date_time.now(),
                    'times': sendtimes,
                    'sendbuf': lora_msg,
                    'address': lora_address,
                    "cmd_client": cmd_client}
            else:
                if address in self.lorawan_send_cmd_dict:
                    self.lorawan_send_cmd_dict[address]['times'] = sendtimes

            logger.info(binascii.b2a_hex(systemdata))
            if LORA_WAN_ENABLE == 1:
                #current_time = time.time() * 1000
                self.dp_lorawan.lorawan_send_cmd(lora_address, lora_msg)
                #logger.info("lorawan send cmd times %s" % str(time.time() * 1000 - current_time))

            return True
        except Exception, exception:
            logger.error(traceback.format_exc())
            return False

    def upgradeapp_cmd_request(self, client, app_name, cmd_client, sendtimes=0):
        try:
            msgdata = {}

            addr = client.addr
            sequence = client.cmdsmgseq
            client.cmdsmgseq = (1 + sequence) & 0xff
            payloadlen = len(app_name)

            msgdata = {
                'functionCode': APP_UPGRADE_REQ,
                'SeqSequence': sequence,
                'PayloadLen': payloadlen,
                'payload': str(app_name.encode("utf-8")),
                'checksum': 0}

            sendbuf = self.dataConvert.encodeData(msgdata)

            if sendtimes == 0:
                client.send_cmd_dict[sequence] = {
                    'lasttime': dt_date_time.now(),
                    'times': sendtimes,
                    'sendbuf': sendbuf,
                    "cmd_client": cmd_client}
            else:
                if sequence in client.send_cmd_dict:
                    client.send_cmd_dict[sequence]['times'] = sendtimes

            if client.networkType == NBIOT_TYPE:
                self.nbiot_client.nbiot_sendCommand(client.deviceid, sendbuf)
            else:
                self.datawrite(sendbuf, addr)

            return True
        except Exception, exception:
            logger.error(traceback.format_exc())
            return False

    def command_request(self, client, cmd, cmd_client, sendtimes = 0):
        try:
            msgdata = {}
            addr = client.addr
            sequence = client.cmdsmgseq
            client.cmdsmgseq = (1+sequence)&0xff
            payloadlen = len(cmd)
            msgdata ={
                'functionCode': CMD_REQ,
                'SeqSequence': sequence,
                'PayloadLen': payloadlen,
                'payload': cmd,
                'checksum': 0}

            sendbuf = self.dataConvert.encodeData(msgdata)

            if sendtimes == 0:
                client.send_cmd_dict[sequence] = {
                    'lasttime': dt_date_time.now(),
                    'times': sendtimes,
                    'sendbuf': sendbuf,
                    "cmd_client": cmd_client}
            else:
                if sequence in client.send_cmd_dict:
                    client.send_cmd_dict[sequence]['times'] = sendtimes

            if client.networkType == NBIOT_TYPE:
                self.nbiot_client.nbiot_sendCommand(client.deviceid, sendbuf)
            else:
                self.datawrite(sendbuf, addr)

            return True
        except Exception,exception:
            logger.error(traceback.format_exc())
            return False

    def do_command_response(self, client, sequence, payload):
        try:
            res, error_msg, flag, pdu, macaddr = self.data_decode.DecodeCompleteMsg(payload)
            if sequence in client.send_cmd_dict:
                cmdmsg = client.send_cmd_dict[sequence]
                lampid = 0
                if res:

                    if client.gatewayType == 'direct':
                        lampid = client.lampid
                    else:
                        retflag, lampid = self.mysqlDb.get_lampid_by_lampaddr(macaddr)

                    if lampid == 0:
                        return False
                    self.storageTag.storage_update_lamp_devstatus(lampid, 0)

                    if flag != 3:
                        if pdu == 0x300:
                            self.mysqlDb.update_lampstatus(lampid, self.data_decode.lampstatus)
                        if pdu == 0x304:
                            self.mysqlDb.update_lighteness(lampid, self.data_decode.lighteness)
                    else:
                        if pdu == 0x328:
                            self.mysqlDb.get_battery_setting_info(lampid,
                                                                  self.data_decode.BatterySettingInfo)
                        elif pdu == 0x400:
                            self.mysqlDb.get_load_setting_info(lampid,
                                                               self.data_decode.LoadParamSettingInfo)

                        if pdu == 70:
                            result = {"lamp_id": lampid,
                                      'projectid': client.projectid,
                                      'networkid': client.networkid}

                            data = self.data_decode.all_data
                            result.update(data)
                            #logger.info("result %s" % result)
                            self.storageTag.save_db_buffer_dict[lampid] = result

                    if cmdmsg["cmd_client"]:
                        cmdmsg["cmd_client"].transport.write(json.dumps({'result': True, 'msg': "send cmd success!"}) + '\n')

                else:
                    if client.gatewayType == 'direct':
                        self.storageTag.storage_update_lamp_devstatus(client.lampid, 3)
                    if cmdmsg["cmd_client"]:
                        cmdmsg["cmd_client"].transport.write(json.dumps({'result': False, 'msg': "unknown error"}) + '\n')

                del client.send_cmd_dict[sequence]
            return True
        except Exception,exception:
            logger.error(traceback.format_exc())
            del client.send_cmd_dict[sequence]
            return False

    def do_system_setting_response(self, client, sequence, payload):
        try:
            if sequence in client.send_cmd_dict:
                cmdmsg = client.send_cmd_dict[sequence]
                if cmdmsg["cmd_client"]:
                    if payload[0] == 0x00:
                        if payload[2] == 0x00:
                            cmdmsg["cmd_client"].transport.write(
                                json.dumps({'result': True, 'msg': "set system data success!"}) + '\n')
                        else:
                            cmdmsg["cmd_client"].transport.write(
                                json.dumps({'result': False, 'msg': "set system data False!"}) + '\n')
                    else:
                        if payload[2] != 0xFF:
                            cmdmsg["cmd_client"].transport.write(
                                json.dumps({'result': True, 'msg': payload[2:]}) + '\n')
                        else:
                            cmdmsg["cmd_client"].transport.write(
                                json.dumps({'result': False, 'msg': "get system data False!"}) + '\n')

                del client.send_cmd_dict[sequence]
            return True
        except Exception,exception:
            logger.error(traceback.format_exc())
            del client.send_cmd_dict[sequence]
            return False

    def do_upgrade_response(self, client, sequence, payload):
        try:
            if sequence in client.send_cmd_dict:
                cmdmsg = client.send_cmd_dict[sequence]
                self.dataConvert.print_string2hex(payload)
                respFlag = struct.unpack('B', payload[0])[0]
                logger.error(respFlag)
                logger.error(type(respFlag))
                if cmdmsg["cmd_client"]:
                    if respFlag == 0x00:
                        cmdmsg["cmd_client"].transport.write(
                                json.dumps({'result': True, 'msg': "start upgrade process success!"}) + '\n')
                    elif respFlag == 0x01:
                        cmdmsg["cmd_client"].transport.write(
                                json.dumps({'result': False, 'msg': "Project name error!"}) + '\n')
                    elif respFlag == 0x02:
                        cmdmsg["cmd_client"].transport.write(
                                json.dumps({'result': False, 'msg': "Version is latest!"}) + '\n')
                    else:
                        cmdmsg["cmd_client"].transport.write(
                                json.dumps({'result': False, 'msg': "Unknow error"}) + '\n')
                del client.send_cmd_dict[sequence]
            else:
                logger.error("sequence not in client.send_cmd_dict")

            return True
        except Exception,exception:
            logger.error(traceback.format_exc())
            del client.send_cmd_dict[sequence]
            return False

    def do_data_report_responese(self, client, sequence, flag=True):
        try:
            msgdata = {}
            if flag == True:
                msgdata = {
                    'functionCode': DATA_SYNC_RESP,
                    'SeqSequence': sequence,
                    'PayloadLen': 0,
                    'payload': [],
                    'checksum': 0}
            else:
                msgdata = {
                    'functionCode': DATA_SYNC_RESP,
                    'SeqSequence': sequence,
                    'PayloadLen': -1,
                    'payload': [0xF3],
                    'checksum': 0}
            sendbuf = self.dataConvert.encodeData(msgdata)
            if client.networkType == NBIOT_TYPE:
                self.nbiot_client.nbiot_sendCommand(client.deviceid, sendbuf)
            else:
                self.datawrite(sendbuf, client.addr)

            return True
        except Exception, exception:
            logger.error(traceback.format_exc())
            return False

    def do_ulp_data_report_responese(self, addr, networkType, sequence, flag=True):
        try:
            msgdata = {}
            if flag == True:
                msgdata = {
                    'functionCode': ULP_DATA_REPORT_RESP,
                    'SeqSequence': sequence,
                    'PayloadLen': 0,
                    'payload': [],
                    'checksum': 0}
            else:
                msgdata = {
                    'functionCode': ULP_DATA_REPORT_RESP,
                    'SeqSequence': sequence,
                    'PayloadLen': -1,
                    'payload': [0xF3],
                    'checksum': 0}
            sendbuf = self.dataConvert.encodeData(msgdata)
            if networkType == NBIOT_TYPE:
                self.nbiot_client.nbiot_sendCommand(addr, sendbuf)
            else:
                self.datawrite(sendbuf, addr)

            return True
        except Exception, exception:
            logger.error(traceback.format_exc())
            return False

    def add_data_to_save(self, client, payload):
        response_flag = False
        lampid = 0

        try:
            res, error_msg, flag, pdu, macaddr = self.data_decode.DecodeCompleteMsg(payload)
            if client.gatewayType == 'direct':
                lampid = client.lampid
            else:
                retflag, lampid = self.mysqlDb.get_lampid_by_lampaddr(macaddr)
                if retflag == False:
                    logger.error("not found lamp addr %s" % str(macaddr))
                    return response_flag

            if res:
                if flag == 3 and pdu == 70:
                    self.storageTag.storage_update_lamp_devstatus(lampid, 0)
                    result = {"lamp_id": lampid,
                              'projectid': client.projectid,
                              'networkid': client.networkid}
                    # logger.info("result %s"%result)
                    data = self.data_decode.all_data
                    result.update(data)
                    self.storageTag.save_db_buffer_dict[lampid] = result
                    response_flag = True
            else:
                self.storageTag.storage_update_lamp_devstatus(lampid, 3)

            return response_flag
        except Exception,exception:
            logger.error(traceback.format_exc())
            return response_flag

    def lorawan_save_data(self, addr, payload, rssi, snr):

        int_address = addr
        lampid = 0
        projectid = 0
        networkid = 0
        devicetype = 0
        if int_address not in self.lorawan_netlists:
            devicesn = str(int(addr, 16))
            had_register, networkinfo = self.mysqlDb.get_network_info_with_sn(devicesn)

            logger.info("networkinfo %s, addr %s" % (str(networkinfo), devicesn))
            logger.info("had_register %s" % str(had_register))
            if had_register == True:
                netid = networkinfo['networkid']
                logger.info("networkid %s" % str(netid))

                udpclient = UDPServerProtocol(self, networkinfo['projectid'], netid,
                                              networkinfo['devid'], networkinfo['protocoltype'],
                                              networkinfo['gatewaytype'], '',
                                              networkinfo['patrolinterval'], networkinfo['devicetype'])
                self.lorawan_netlists[int_address] = udpclient
                self.lorawan_netlists[int_address].updateNetworkAddr(addr)
                self.lorawan_netlists[int_address].lasttime = dt_date_time.now()
                lampid = self.lorawan_netlists[int_address].lampid
                projectid = networkinfo['projectid']
                networkid = netid
                devicetype = networkinfo['devicetype']
            else:
                result, lamp_info = self.mysqlDb.get_lampinfo_groupby_address(addr)
                if not result:
                    result, lamp_info = self.mysqlDb.get_lampinfo_groupby_address(addr)
                if result:
                    lampid = lamp_info["id"]
                    projectid = lamp_info['projectid']
                    networkid = lamp_info['networkid']
                else:
                    return
        else:
            lampid = self.lorawan_netlists[int_address].lampid
            projectid = self.lorawan_netlists[int_address].projectid
            networkid = self.lorawan_netlists[int_address].networkid
            devicetype = self.lorawan_netlists[int_address].devicetype
            self.lorawan_netlists[int_address].lasttime = dt_date_time.now()
        self.storageTag.storage_update_network(networkid, rssi, snr, 3)
        try:
            if devicetype == 2:
                self.dataConvert.print_string2hex(str(bytearray.fromhex(payload)))
                return
            #self.dataConvert.print_string2hex(str(bytearray. fromhex(payload)))
            res, error_msg, flag, pdu, macaddr = self.data_decode.DecodeCompleteMsg(str(bytearray.fromhex(payload)))
            #logger.info("res %s, error_msg %s, flag %s, pdu %s" % (res, error_msg, flag, pdu))
            #logger.info("self.lorawan_send_cmd_dict %s, int_address %s" % (str(self.lorawan_send_cmd_dict), int_address))
            if int_address in self.lorawan_send_cmd_dict:
                cmdmsg = self.lorawan_send_cmd_dict[int_address]
                logger.info("lorawan macaddr %s" % (macaddr))
                if res:
                    logger.info("lorawan macaddr %s" % (macaddr))
                    self.storageTag.storage_update_lamp_devstatus(lampid, 0)
                    if flag == 0x80:
                        pass
                    elif flag != 3:
                        if pdu == 0x300:
                            self.mysqlDb.update_lampstatus(lampid, self.data_decode.lampstatus)
                        if pdu == 0x304:
                            self.mysqlDb.update_lighteness(lampid, self.data_decode.lighteness)
                    else:
                        if pdu == 0x328:
                            self.mysqlDb.get_battery_setting_info(lampid,
                                                                  self.data_decode.BatterySettingInfo)
                        elif pdu == 0x400:
                            self.mysqlDb.get_load_setting_info(lampid,
                                                               self.data_decode.LoadParamSettingInfo)

                        if pdu == 70:
                            result = {"lamp_id": lampid,
                                      'projectid': projectid,
                                      'networkid': networkid}

                            data = self.data_decode.all_data
                            result.update(data)

                            self.storageTag.save_db_buffer_dict[lampid] = result
                            #logger.info("result %s" % str(result))

                    if cmdmsg["cmd_client"]:
                        cmdmsg["cmd_client"].transport.write(
                            json.dumps({'result': True, 'msg': "send cmd success!"}) + '\n')

                else:
                    logger.info("res %s, error_msg %s, flag %s, pdu %s" % (res, error_msg, flag, pdu))
                    self.storageTag.storage_update_lamp_devstatus(lampid, 3)
                    if cmdmsg["cmd_client"]:
                        cmdmsg["cmd_client"].transport.write(
                            json.dumps({'result': False, 'msg': error_msg}) + '\n')
                del self.lorawan_send_cmd_dict[int_address]
            elif res:
                if pdu == 70 and flag == 3:

                    self.storageTag.storage_update_lamp_devstatus(lampid, 0)
                    lampid_exist_flag = 0

                    result = {"lamp_id": lampid,
                              'projectid': projectid,
                              'networkid': networkid}
                    #logger.info("result %s" % str(result))
                    data = self.data_decode.all_data
                    result.update(data)
                    self.storageTag.save_db_buffer_dict[lampid] = result
                    #logger.info("result %s" % str(result))
            else:
                self.storageTag.storage_update_lamp_devstatus(lampid, 3)
        except Exception,exception:
            logger.error(traceback.format_exc())


    def do_data_report_request(self, client, sequence, payload):
        response_flag = False
        logger.info("networkType 0x%x" % client.networkType)
        logger.info("gatewayType %s" % client.gatewayType)
        try:
            if client.gatewayType == 'direct':
                response_flag = self.add_data_to_save(client, payload)
            else:
                packetcount = self.dataConvert.BYTEToInt(payload[0])
                logger.info(packetcount)
                packetindex = 0
                #self.dataConvert.print_string2hex(payload)
                for i in range(0, packetcount):
                    packetindex += 1
                    packetlen = self.dataConvert.BYTEToInt(payload[packetindex])
                    packetindex += 1
                    #logger.info("packetindex %d, packetlen %d" % (packetindex, packetlen))

                    subpayloadlen = packetindex+packetlen
                    subpayload = payload[packetindex:subpayloadlen]
                    packetindex += packetlen
                    #self.dataConvert.print_string2hex(subpayload)
                    response_flag = self.add_data_to_save(client, subpayload)

        except Exception,exception:
            logger.error(traceback.format_exc())
            return False
        self.do_data_report_responese(client, sequence, response_flag)
        return True

    def do_ulp_data_report_request(self, addr, networktype, devid, sequence, payload):
        response_flag = False

        try:
            res, error_msg = self.envmonitor_decode.decode_all_data(payload)
            if res:
                response_flag = True

                result = {"devid": devid}
                # logger.info("result %s"%result)
                data = self.envmonitor_decode.all_data
                result.update(data)
                logger.info(str(result))
                self.storageTag.save_envmonitor_data_dict[devid] = result

            self.do_ulp_data_report_responese(addr, networktype, sequence, response_flag)
        except Exception,exception:
            logger.error(traceback.format_exc())
            return False

        return True

    def do_lamp_group_cmd(self, lampids, actiontype, value):

        try:
            lorawan_group_cmd_list = []
            nbiot_group_cmd_list = []
            nbiot_deviceid_list = []
            udp_group_cmd_list = []
            senddata = ''
            result, lampinfo_list = self.storageTag.mysqlDb.get_lampinfos_by_lampid(lampids)
            logger.info(str(lampinfo_list))
            if actiontype == 0:
                senddata = self.storageTag.data_encode.EncodeCompleteCmd('0', 6, 772, [value])
            elif actiontype == 2:
                lightvalue = self.storageTag.mysqlDb.get_policycmd_by_id(value)
                senddata = self.storageTag.data_encode.EncodeCompleteCmd('0', 6, 772, lightvalue)
            else:
                return False
            for lampinfo in lampinfo_list:
                if lampinfo['status'] == 0:
                    continue
                if lampinfo['protocoltype'] == LORA_WAN_TYPE:
                    groupcmd = {
                        'networkid': lampinfo['networkid'],
                        'address': lampinfo['address'],
                        'senddata': senddata
                    }
                    lorawan_group_cmd_list.append(groupcmd)
                if lampinfo['protocoltype'] == NBIOT_TYPE:
                    nbiot_deviceid_list.append(lampinfo['deviceid'])
                    groupcmd = {
                        'networkid': lampinfo['networkid'],
                        'address': lampinfo['address'],
                        'senddata': senddata
                    }
                    nbiot_group_cmd_list.append(groupcmd)
                if lampinfo['protocoltype'] == UDP_TYPE:
                    groupcmd = {
                        'networkid': lampinfo['networkid'],
                        'address': lampinfo['address'],
                        'senddata': senddata
                    }
                    udp_group_cmd_list.append(groupcmd)
            if len(lorawan_group_cmd_list) > 0:
                threads.deferToThread(self.lorawan_send_group_cmd_thread, lorawan_group_cmd_list)
            if len(nbiot_group_cmd_list) > 0:
                groupcmd = {
                    'devicelist': nbiot_deviceid_list,
                    'senddata': senddata
                }
                threads.deferToThread(self.nbiot_send_group_cmd_thread, groupcmd)
            if len(udp_group_cmd_list) > 0:
                threads.deferToThread(self.udp_send_group_cmd_thread, udp_group_cmd_list)
        except Exception,exception:
            logger.error(traceback.format_exc())
            return False

        return True

    def do_send_transmission_cmd(self, lampid, devicetype, senddata):

        try:
            if devicetype == 2:
                result, lampinfo_list = self.storageTag.mysqlDb.get_streetlampinfos_by_lampid(lampid)
                lora_address = covertLorawanAddress(lampinfo_list['address'])
                lora_msg = covertLorawanMsg(binascii.b2a_hex(senddata))
                self.dp_lorawan.lorawan_send_cmd(lora_address, lora_msg)
        except Exception,exception:
            logger.error(traceback.format_exc())
            return False

        return True

    def UDPServer_main_thread(self):
        logger.info("UDPServer_main_thread threadid: %d"% (getThreadId()))
        while True:
            current_time = dt_date_time.now()
            try:
                if not self.is_UDPdecode_thread_locked:
                    self.decodeThread = threads.deferToThread(self.UDPDecodeDataThread)
                    self.decodeThread.addCallback(self.send_data_success)

                if(current_time - self.UDPheart_beat_record_time).seconds >= HEART_CHECK_INTERVAL :
                    self.sendHeartBeatThread = threads.deferToThread(self.UDPChek_heart_beat_thread)
                    self.sendHeartBeatThread.addCallback(self.send_data_success)

            except Exception,e:
                logger.error("UDPServer_main_thread error %s"%str(e))
                pass
            time.sleep(1)
        return {'result':True,
                'message':"UDPServer_main_thread:main thread over"}

    def ReceiveCMD_thread(self):
        logger.info("ReceiveCMD_thread threadid: %d" % (getThreadId()))
        while True:
            try:
                cmdmsg = global_buffer.global_get_cmdmsg()
                client = {}
                if cmdmsg["cmd_type"] == 'lamp_group_cmd':
                    logger.info(str(cmdmsg))
                    self.do_lamp_group_cmd(cmdmsg["lampids"], cmdmsg["actiontype"], cmdmsg["value"])
                    continue
                if cmdmsg["cmd_type"] == 'send_transmission_cmd':
                    logger.info(str(cmdmsg))
                    self.do_send_transmission_cmd(cmdmsg["lampid"], cmdmsg["devicetype"], cmdmsg["senddata"])
                    continue
                if cmdmsg["protocoltype"] == LORA_WAN_TYPE:
                    if cmdmsg["cmd_type"] == 'set_patrol_cmd':
                        senddata = PackSendData.EncodeLorawanPatrolCmd('0', 128, cmdmsg["senddata"])
                        self.lorawan_rw_cmd_request(cmdmsg["address"], senddata, cmdmsg["cmd_client"])
                    elif cmdmsg["cmd_type"] == 'get_patrol_cmd':
                        senddata = PackSendData.EncodeLorawanPatrolCmd('0', 128, cmdmsg["senddata"])
                        self.lorawan_rw_cmd_request(cmdmsg["address"], senddata, cmdmsg["cmd_client"])
                    else:
                        self.lorawan_rw_cmd_request(cmdmsg["address"], cmdmsg["senddata"], cmdmsg["cmd_client"])
                else:
                    if cmdmsg["protocoltype"] == UDP_TYPE:
                        networkid = cmdmsg["networkid"]
                        if networkid in self.connections:
                            client = self.connections[networkid]
                        else:
                            if cmdmsg["cmd_client"]:
                                cmdmsg["cmd_client"].transport.write(json.dumps(
                                    {'result': False, 'msg': 'current network is not online'}) + '\n')
                            continue
                    elif cmdmsg["protocoltype"] == NBIOT_TYPE:
                        networkid = cmdmsg["networkid"]
                        if networkid in self.nbiot_netlists:
                            client = self.nbiot_netlists[networkid]
                        else:
                            if cmdmsg["cmd_client"]:
                                cmdmsg["cmd_client"].transport.write(json.dumps(
                                    {'result': False, 'msg': 'current network is not online'}) + '\n')
                            continue
                    else:
                        continue
                    logger.error(str(client))
                    logger.error(str(cmdmsg))
                    if cmdmsg["cmd_type"] == 'set_patrol_cmd':
                        self.systemdata_rw_cmd_request(client, 0, PATROL_SETTING_TYPE, cmdmsg["senddata"]/5,
                                                       cmdmsg["cmd_client"])
                    elif cmdmsg["cmd_type"] == 'get_patrol_cmd':
                        self.systemdata_rw_cmd_request(client, 1, PATROL_SETTING_TYPE, cmdmsg["senddata"]/5,
                                                       cmdmsg["cmd_client"])
                    elif cmdmsg["cmd_type"] == 'set_server_addr_cmd':
                        self.systemdata_rw_cmd_request(client, 0, SERVER_ADDR_TYPE, cmdmsg["senddata"],
                                                       cmdmsg["cmd_client"])
                    elif cmdmsg["cmd_type"] == 'get_server_addr_cmd':
                        self.systemdata_rw_cmd_request(client, 1, SERVER_ADDR_TYPE, cmdmsg["senddata"],
                                                       cmdmsg["cmd_client"])
                    elif cmdmsg["cmd_type"] == 'get_software_version_cmd':
                        self.systemdata_rw_cmd_request(client, 1, SYSTEM_VERSION_TYPE, cmdmsg["senddata"],
                                                       cmdmsg["cmd_client"])
                    elif cmdmsg["cmd_type"] == 'app_upgrade_cmd':
                        self.upgradeapp_cmd_request(client, cmdmsg["senddata"], cmdmsg["cmd_client"])
                    else:
                        self.command_request(client, cmdmsg["senddata"], cmdmsg["cmd_client"])


            except Exception, e:
                logger.error("ReceiveCMD_thread error %s" % str(e))
                pass
            time.sleep(1)
        return {'result':True,
                'message':"ReceiveCMD_thread:Cmd thread over"}

    def send_data_success(self,result):
         pass
         #logger.info(result.get("message",'no message'))

    def UDPDecodeDataThread(self):

        try:
            self.is_UDPdecode_thread_locked = True
            self.decode_thread_record_time = dt_date_time.now()

            if len(self.msg_buffer) <= 0:
                self.is_UDPdecode_thread_locked = False
                return {'result':False,
                        'message':"decodeDataThread:decodeDataThread over no buffer ok record time %s"%self.decode_thread_record_time}
            decode_buffer = []
            decode_buffer = [msg for msg in self.msg_buffer]

            del self.msg_buffer[:]
            for item in decode_buffer:
                protype = item["protype"]
                addr = item["addr"]
                udpmsgdata = item["msgdata"]
                retflag, msgdata = self.dataConvert.decodeData(udpmsgdata)
                if retflag == False:
                    continue

                if msgdata["functionCode"] == REGISTER_REQ:

                    logger.info(msgdata['payload'].encode("utf-8"))
                    register_info = msgdata['payload'].encode("utf-8").split("-")

                    had_register = False

                    if len(register_info) > 1:
                        had_register, networkinfo = self.mysqlDb.get_network_info_with_sn(register_info[1])

                    logger.info("networkinfo %s" % str(networkinfo))
                    logger.info("had_register %s" % str(had_register))
                    if had_register == True:
                        netid = networkinfo['networkid']
                        logger.info("networkid %s" % str(netid))

                        if len(register_info) > 2:
                            self.mysqlDb.update_network_simid(netid, register_info[2])
                        if register_info[0] == 'register':

                            if netid not in self.connections:
                                udpclient = UDPServerProtocol(self, networkinfo['projectid'], netid,
                                                              networkinfo['devid'], networkinfo['protocoltype'],
                                                              networkinfo['gatewaytype'], networkinfo['networkname'],
                                                              networkinfo['patrolinterval'])
                                self.connections[netid] = udpclient
                            self.connections[netid].updateNetworkAddr(addr)
                            self.registerResponse(addr, netid, networkinfo['protocoltype'])


                        elif register_info[0] == 'NBIot':
                            if netid not in self.nbiot_netlists:
                                nbclient = UDPServerProtocol(self, networkinfo['projectid'], netid,
                                                             networkinfo['devid'], networkinfo['protocoltype'],
                                                             networkinfo['gatewaytype'], networkinfo['networkname'],
                                                             networkinfo['patrolinterval'])
                                self.nbiot_netlists[netid] = nbclient
                            self.nbiot_netlists[netid].updateNetworkAddr(addr)
                            self.storageTag.storage_update_nbiot_deviceid(netid, addr)
                            patrol_time = networkinfo['patrolinterval']/5
                            patrol_time = patrol_time if int(patrol_time) > 0 else 1
                            #global_buffer.system_post_cmd(netid, 0, networkinfo['protocoltype'], 0, None,
                            #                              'set_patrol_cmd', int(patrol_time))
                            self.registerResponse(addr, netid, NBIOT_TYPE)
                    else:
                        logger.info("not register")
                        if protype == 'udp':
                            self.registerResponse(addr, 0, 0, False)
                        else:
                            self.registerResponse(addr, 0, NBIOT_TYPE, False)

                if msgdata["functionCode"] == ULP_REGISTER_REQ:

                    logger.info(msgdata['payload'].encode("utf-8"))
                    register_info = msgdata['payload'].encode("utf-8").split("-")

                    had_register = False

                    if len(register_info) > 1:
                        had_register, networkinfo = self.mysqlDb.get_network_info_with_sn(register_info[1])

                    logger.info("networkinfo %s" % str(networkinfo))
                    logger.info("had_register %s" % str(had_register))
                    if had_register == True:
                        netid = networkinfo['networkid']
                        logger.info("networkid %s" % str(netid))

                        self.registerResponse(addr, netid, networkinfo['protocoltype'], True, ULP_REGISTER_RESP)
                    else:
                        logger.info("not register")
                        if protype == 'udp':
                            self.registerResponse(addr, 0, 0, False, ULP_REGISTER_RESP)
                        else:
                            self.registerResponse(addr, 0, NBIOT_TYPE, False, ULP_REGISTER_RESP)

                if msgdata["functionCode"] == HEARTBEAT_REQ:

                    heartbeat_info = msgdata['payload'].encode("utf-8").split("-")
                    logger.info(msgdata['payload'].encode("utf-8"))
                    networkid = int(heartbeat_info[0])
                    netCsq = heartbeat_info[1]
                    devState = heartbeat_info[2]

                    protocoltype = UDP_TYPE

                    if protype == 'nbiot':
                        protocoltype = NBIOT_TYPE
                        self.storageTag.storage_update_network(networkid, netCsq, 0)
                        client = self.getClientBydevid(addr)
                        if client:
                            client.updateNetworkAddr(addr)
                        else:
                            self.registerResponse(addr, 0, protocoltype, False)
                    else:
                        if networkid not in self.connections :
                            self.registerResponse(addr, 0, protocoltype, False)
                        else:
                            self.storageTag.storage_update_network(networkid, netCsq, 0)
                            # add to update lamp devstatus
                            oldaddr = self.getAddrByNetworkid(networkid)
                            if oldaddr != addr:
                                self.connections[networkid].updateNetworkAddr(addr)
                            self.connections[networkid].updateConnectTime(int(netCsq), int(devState))

                if msgdata["functionCode"] == CMD_RESP:
                    client = None
                    protocoltype = UDP_TYPE
                    if protype == 'udp':
                        client = self.getClientByAddr(addr)
                    elif protype == 'nbiot':
                        protocoltype = NBIOT_TYPE
                        client = self.getClientBydevid(addr)

                    if client != False:
                        self.do_command_response(client, msgdata["SeqSequence"], msgdata["payload"])
                    else:
                        self.registerResponse(addr, 0, protocoltype, False)

                if msgdata["functionCode"] == DATA_REPORT_REQ:
                    #logger.info("addr %s" % str(addr))
                    client = None
                    protocoltype = UDP_TYPE
                    if protype == 'udp':
                        client = self.getClientByAddr(addr)
                    elif protype == 'nbiot':
                        protocoltype = NBIOT_TYPE
                        client = self.getClientBydevid(addr)
                        if client:
                            client.updateNetworkAddr(addr)
                    if client != False:
                        self.do_data_report_request(client, msgdata["SeqSequence"], msgdata["payload"])
                    else:
                        logger.error("deviceid %s not register" % str(addr))
                        self.registerResponse(addr, 0, protocoltype, False)

                if msgdata["functionCode"] == ULP_DATA_REPORT_REQ:
                    #logger.info("addr %s" % str(addr))

                    protocoltype = UDP_TYPE
                    if protype == 'nbiot':
                        protocoltype = NBIOT_TYPE
                    networkid = 0
                    if len(msgdata["payload"]) > 4:
                        networkid = self.data_decode.DWordToInt(msgdata["payload"][0:4])
                    else:
                        continue
                    had_register, devid = self.mysqlDb.get_device_info_with_networkid(networkid)

                    if had_register:
                        self.do_ulp_data_report_request(addr, protocoltype, devid, msgdata["SeqSequence"],
                                                        msgdata["payload"][4:])

                    else:
                        logger.error("deviceid %s not register" % str(networkid))
                        self.registerResponse(addr, 0, protocoltype, False, ULP_REGISTER_RESP)

                if msgdata["functionCode"] == SYSTEM_RW_CMD_RESP:
                    client = None
                    protocoltype = UDP_TYPE
                    if protype == 'udp':
                        client = self.getClientByAddr(addr)
                    elif protype == 'nbiot':
                        protocoltype = NBIOT_TYPE
                        client = self.getClientBydevid(addr)
                    if client != False:
                        self.do_system_setting_response(client, msgdata["SeqSequence"], msgdata["payload"])
                    else:
                        self.registerResponse(addr, 0, protocoltype, False)

                if msgdata["functionCode"] == APP_UPGRADE_RESP:
                    client = None
                    protocoltype = UDP_TYPE
                    if protype == 'udp':
                        client = self.getClientByAddr(addr)
                    elif protype == 'nbiot':
                        protocoltype = NBIOT_TYPE
                        client = self.getClientBydevid(addr)

                    if client != False:
                        self.do_upgrade_response(client, msgdata["SeqSequence"], msgdata["payload"])
                    else:
                        self.registerResponse(addr, 0, protocoltype, False)
                time.sleep(0.002)
            del decode_buffer[:]
            self.is_UDPdecode_thread_locked = False
            return {'result': True,
                    'message': "decodeDataThread:decodeDataThread over is ok record time %s" %
                               self.decode_thread_record_time}
        except Exception, exception:
            logger.error(traceback.format_exc())
            self.is_UDPdecode_thread_locked = False
            return {'result':False,
                    'message':"decodeDataThread:decodeDataThread over is ok record time %s"%self.decode_thread_record_time}

    def UDPChek_heart_beat_thread(self):
        try:
            current_time = dt_date_time.now()
            if NBIOT_ENABLE == 1:
                self.nbiot_client.refreshToken()
            if LORA_WAN_ENABLE == 1:
                lora_address_keys = self.lorawan_send_cmd_dict.keys()
                for addressdictkey in lora_address_keys:
                    time.sleep(0.001)
                    cmdmsg = self.lorawan_send_cmd_dict[addressdictkey]

                    last_time = cmdmsg["lasttime"]
                    if (current_time - last_time).seconds > 30:
                        sendtimes = cmdmsg["times"]
                        if sendtimes < 3:
                            sendtimes += 1
                            self.dp_lorawan.lorawan_send_cmd(cmdmsg["address"], cmdmsg["sendbuf"])
                            cmdmsg["times"] = sendtimes
                            cmdmsg["lasttime"] = current_time
                        else:
                            if cmdmsg["cmd_client"]:
                                cmdmsg["cmd_client"].transport.write(json.dumps(
                                    {'result': False, 'msg': 'send cmd time out!!!'}) + '\n')
                            del self.lorawan_send_cmd_dict[addressdictkey]

            nbiot_deviceid_keys = self.nbiot_send_cmd_dict.keys()
            for deviceid in nbiot_deviceid_keys:
                time.sleep(0.001)
                cmdmsg = self.nbiot_send_cmd_dict[deviceid]

                last_time = cmdmsg["lasttime"]
                if (current_time - last_time).seconds > 30:
                    sendtimes = cmdmsg["times"]
                    if sendtimes < 3:
                        sendtimes += 1
                        self.nbiot_client.nbiot_sendCommand(cmdmsg["deviceid"], cmdmsg["sendbuf"])
                        cmdmsg["times"] = sendtimes
                        cmdmsg["lasttime"] = current_time
                    else:
                        if cmdmsg["cmd_client"]:
                            cmdmsg["cmd_client"].transport.write(json.dumps(
                                {'result': False, 'msg': 'send cmd time out!!!'}) + '\n')
                        del self.nbiot_send_cmd_dict[deviceid]

            connects_keys = self.connections.keys()
            for clientdictkey in connects_keys:
                time.sleep(0.001)
                client_item = self.connections[clientdictkey]
                if client_item == False:
                    continue
                if (current_time - client_item.lasttime) > timedelta(seconds=300):
                    if client_item.send_cmd_dict:
                        del client_item.send_cmd_dict

                    client_item.cleanUp()
                    continue
                senddict_keys = client_item.send_cmd_dict.keys()
                for senddictkey in senddict_keys:
                    cmdmsg = client_item.send_cmd_dict[senddictkey]

                    last_time = cmdmsg["lasttime"]
                    if (current_time - last_time).seconds > 30:
                        sendtimes = cmdmsg["times"]
                        if sendtimes < 3:
                            sendtimes += 1
                            if client_item.networkType == NBIOT_TYPE:
                                self.nbiot_client.nbiot_sendCommand(client_item.deviceid, cmdmsg["sendbuf"])
                            else:
                                self.datawrite(cmdmsg["sendbuf"], client_item.addr)
                            cmdmsg["times"] = sendtimes
                            cmdmsg["lasttime"] = current_time
                        else:
                            if cmdmsg["cmd_client"]:
                                cmdmsg["cmd_client"].transport.write(json.dumps(
                                    {'result': False, 'msg': 'send cmd time out!!!'}) + '\n')
                            del client_item.send_cmd_dict[senddictkey]

            nbiot_lampid_keys = self.nbiot_netlists.keys()
            for clientdictkey in nbiot_lampid_keys:
                client_item = self.nbiot_netlists[clientdictkey]
                if client_item == False:
                    continue
                if (current_time - client_item.lasttime) > timedelta(hours=2):
                    logger.info("current time %s, last time  %s" %(current_time.strftime('%Y-%m-%d %H:%M:%S'), client_item.lasttime.strftime('%Y-%m-%d %H:%M:%S')))
                    client_item.cleanUp()
                    continue

            lorawan_lamp_keys = self.lorawan_netlists.keys()
            for clientdictkey in lorawan_lamp_keys:
                client_item = self.lorawan_netlists[clientdictkey]
                if client_item == False:
                    continue
                if (current_time - client_item.lasttime) > timedelta(hours=2):
                    client_item.cleanUp()
                    continue

            self.UDPheart_beat_record_time = dt_date_time.now()
            return {'result':True,
                    'message':"UDPheart_beat_record_time : check heart beat thread end record time %s" % str(self.UDPheart_beat_record_time)}
        except Exception,exception:
            logger.error(traceback.format_exc())
            self.UDPheart_beat_record_time = dt_date_time.now()
            return {'result':False,
                    'message':"UDPheart_beat_record_time : check heart beat thread end record time %s" % str(self.UDPheart_beat_record_time)}

    def lorawan_send_group_cmd_thread(self, group_cmd_list):
        try:
            groupcmdlist = [cmd for cmd in group_cmd_list]
            for cmd in groupcmdlist:
                lora_address = covertLorawanAddress(cmd['address'])
                lora_msg = covertLorawanMsg(binascii.b2a_hex(cmd['senddata']))
                self.dp_lorawan.lorawan_send_cmd(lora_address, lora_msg)
            return {'result': True,
                    'message': "lorawan_send_group_cmd_thread"}
        except Exception,exception:
            logger.error(traceback.format_exc())
            self.UDPheart_beat_record_time = dt_date_time.now()
            return {'result': False,
                    'message': "lorawan_send_group_cmd_thread"}

    def nbiot_send_group_cmd_thread(self, group_cmd):
        try:
            payloadlen = len(group_cmd["senddata"])
            msgdata = {
                'functionCode': CMD_REQ,
                'SeqSequence': 1,
                'PayloadLen': payloadlen,
                'payload': group_cmd["senddata"],
                'checksum': 0}

            sendbuf = self.dataConvert.encodeData(msgdata)
            self.nbiot_client.nbiot_senddCommand_fordevlist(group_cmd["devicelist"], sendbuf)
            return {'result': True,
                    'message': "nbiot_send_group_cmd_thread"}
        except Exception,exception:
            logger.error(traceback.format_exc())
            self.UDPheart_beat_record_time = dt_date_time.now()
            return {'result': False,
                    'message': "nbiot_send_group_cmd_thread"}

    def udp_send_group_cmd_thread(self, group_cmd_list):
        try:
            groupcmdlist = [cmd for cmd in group_cmd_list]
            for cmd in groupcmdlist:
                if cmd['networkid'] in self.connections:
                    client = self.nbiot_netlists[cmd['networkid']]
                    self.command_request(client, cmd["senddata"], None, 1)
            return {'result': True,
                    'message': "udp_send_group_cmd_thread"}
        except Exception,exception:
            logger.error(traceback.format_exc())
            self.UDPheart_beat_record_time = dt_date_time.now()
            return {'result': False,
                    'message': "udp_send_group_cmd_thread"}


